import Ball from "../Ball";
import Define from "../common/Define";
import Shake from "../Shake";
import Common from "../common/Common";
import FrameAnimation from "../common/FrameAnimation";
import FramaAnimations from "../common/FramaAnimations";
import Bullet from "../Bullet";
import UserInfo from "../UserInfo";
import LevelInfo from "../Levellnfo";
import TimeTaskManager from "./TimeTaskManager";
import UIManager from "./UIManager";
import LDataGoldManager from "../datas/LDataGoldManager";
import LDataStoncolourManager from "../datas/LDataStoncolourManager";
import LDataStoneManager from "../datas/LDataStoneManager";
import GoldCtr from "../GoldCtr";
import ParticleEffectManager from "./ParticleEffectManager";
import ParticleEffect from "../ParticleEffect";
import WXHelper from "../common/WXHelper";
import CannonCtr from "../CannonCtr";
import CannonManager from "./CannonManager";
import LDataCannonManager from "../datas/LDataCannonManager";
import ResManager from "./ResManager";
import HttpManager from "./HttpManager";
import LDataSceneManager from "../datas/LDataSceneManager";
import SoundManager from "./SoundManager";

// Learn TypeScript:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/typescript.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class GameManager extends cc.Component {

    @property(cc.Node)
    nodeBalls: cc.Node = null;

    @property(cc.Node)
    nodeGolds:cc.Node = null;

    @property(cc.Node)
    nodeParticleEffects:cc.Node = null;

    @property(cc.Node)
    nodeBg:cc.Node = null;

    @property(cc.Node)
    nodeGameRoot:cc.Node = null;//游戏子节点

    @property(cc.Node)
    nodeUiRoot:cc.Node = null;//ui 子节点

    @property(cc.Node)
    nodeGold:cc.Node = null;//ui金币

    @property(cc.Node)
    nodeBallRoot:cc.Node = null;//球体的根节点

    @property(cc.Node)
    nodeGoldRoot:cc.Node = null;//球体的根节点

    @property(cc.Node)
    nodePrompt: cc.Node = null; //提示

    @property(cc.Sprite)
    display: cc.Sprite = null; //微信子域

    @property(cc.Node)
    textAddGold: cc.Node = null; //金币增加
    

    @property(cc.Node)
    addPowerEffect:cc.Node = null;

    @property(cc.Node)
    sceneBgs:cc.Node = null;

    @property(cc.Node)
    nodeSoundRoot:cc.Node = null;

    @property(cc.Node)
    sceneObjs:cc.Node = null;
    

    wxHelper:WXHelper = null;

    private bgInitPos:cc.Vec2 = null;

    private isCanMoveCannon:boolean = false;
    private moveToPos:cc.Vec2 = null;
    

    private totalShootTime:number = 0;
    private totalShootCount:number = 0;
 
    public static instance:GameManager = null;

    private bulletArr:Bullet[] = [];
    private ballArr:Ball[] = [];
    private goldArr:GoldCtr[] = [];

    private totalShootAnimaTime:number = 0;
    //当前坦克
    curCannonCtr:CannonCtr = null;

    private nodeBullet:cc.Node = null;//子弹

    private newMethod(): CannonCtr {
        return null;
    }

    start () {
        this.wxHelper = new WXHelper();
        this.wxHelper.initWXHelper();
        this.wxHelper.display = this.display;  
        WXHelper.initRewardedVideoAd();
        //cc.game.setFrameRate(60);
        //初始化数据表
        LDataGoldManager.GetDataById(0);
        LDataStoncolourManager.GetDataById(0);
        LDataStoneManager.GetDataById(0);
        LDataCannonManager.GetDataById(0);
        LDataSceneManager.GetDataById(0);
        
        //UserInfo.clearAllDatas();
        //加载玩家本地数据
        UserInfo.loadAllData();




        //初始化数据表完成
        GameManager.instance = this;
        
        if(cc.sys.platform === cc.sys.WECHAT_GAME){
            this.nodeBg.getParent().on(cc.Node.EventType.TOUCH_START, (e: cc.Event.EventTouch) => this.mouseDown(e))
            this.nodeBg.getParent().on(cc.Node.EventType.TOUCH_MOVE, (e: cc.Event.EventTouch) => this.mouseMove(e))
            this.nodeBg.getParent().on(cc.Node.EventType.TOUCH_END, (e: cc.Event.EventTouch) => this.mouseEnd(e))
            this.nodeBg.getParent().on(cc.Node.EventType.TOUCH_CANCEL, (e: cc.Event.EventTouch) => this.mouseEnd(e))
        }else {
            this.nodeBg.getParent().on(cc.Node.EventType.MOUSE_DOWN, (e: cc.Event.EventTouch) => this.mouseDown(e))
            this.nodeBg.getParent().on(cc.Node.EventType.MOUSE_MOVE, (e: cc.Event.EventTouch) => this.mouseMove(e))
            this.nodeBg.getParent().on(cc.Node.EventType.MOUSE_UP, (e: cc.Event.EventTouch) => this.mouseEnd(e))
        }
        
        cc.game.on(cc.game.EVENT_HIDE,this.gameEventHide)
        cc.game.on(cc.game.EVENT_SHOW,this.gameEventShow)
        cc.game.on(cc.game.EVENT_ENGINE_INITED,this.gameEventShow)
    

        this.changeCannonById(UserInfo.curUseCannonId)
            
        TimeTaskManager.addTimeTask(3.5,this.createStone.bind(this));
        this.bgInitPos = this.nodeBg.position;
        Common.isFirstCreatStone = true;    

        //保存几个根节点
        Common.nodeGameRoot = this.nodeGameRoot;
        Common.nodeUiRoot = this.nodeUiRoot;
        Common.nodeBallRoot = this.nodeBallRoot;
        Common.nodeGoldRoot = this.nodeGoldRoot;
        Common.nodeParticleEffects = this.nodeParticleEffects;
        Common.nodePrompt = this.nodePrompt;
        Common.nodeAddGold = this.textAddGold;
        Common.addPowerEffect = this.addPowerEffect;
        Common.nodeSoundRoot = this.nodeSoundRoot;
        Common.offLineRewardCount =  LevelInfo.getOffLineRewardGoldCount();




        this.changeSceneByIndex(UserInfo.getCurSceneIndex(),true)


 
        
        if(Define.gameId == "002"){
            HttpManager.getInstance().getGameState(function(){
                this.enterGame();
            }.bind(this));
        }else{
            this.enterGame();
        }
    }

    enterGame(){
        if(Common.offLineRewardCount > 20){
            UIManager.getInstance().showView(Define.viewOffLineReward);
            UIManager.getInstance().showView(Define.viewUpgrade);
        }else{
            UIManager.getInstance().showView(Define.viewMain);
            UIManager.getInstance().showView(Define.viewUpgrade);
        }
        WXHelper.wxCheckLogin();
    }

    changeCannonById(id = 0){
        let lastPos:cc.Vec2 = new cc.Vec2(320,280)
        if(this.curCannonCtr != null){
            lastPos = this.curCannonCtr.node.position
            this.curCannonCtr.node.destroy()
        }

        Common.curUseCannonId = id
        Common.curDataCannon = LDataCannonManager.GetDataById(Common.curUseCannonId)
        CannonManager.createCannon(id,this.nodeGameRoot,function(cannonCtr:CannonCtr){
            this.curCannonCtr = cannonCtr
            this.curCannonCtr.node.position = lastPos
            this.curCannonCtr.node.setSiblingIndex(2)
            this.removeAllBullet()
            ResManager.loadPrefab("prefabs/bullets/bullet"+Common.curDataCannon.bulletsId.toString(),function(bullet){
                this.nodeBullet = bullet
            }.bind(this))

        }.bind(this));
    }

    changeSceneByIndex(index:number,isFirst:boolean = false){
        for (let i = 0; i < this.sceneBgs.childrenCount; i++) {
            this.sceneBgs.children[i].active = false
        }
        this.sceneBgs.children[index].active = true

        if(index != 0){
            this.sceneObjs.active = false
        }else{
            this.sceneObjs.active = true
        }

        if(index == 2){
            console.log("播放音乐")
            SoundManager.pauseBackGroundSound(false)
        }else{
            SoundManager.pauseBackGroundSound(true)
        }
        
    }

    mouseDown (event:cc.Event.EventTouch){
        this.isCanMoveCannon = true;
        this.moveToPos = event.getLocation();
    }

    mouseMove (event:cc.Event.EventTouch){
        if(!this.isCanMoveCannon){
            return;
        }
        this.moveToPos = event.getLocation();
    }

    mouseEnd (event:cc.Event.EventTouch){
        this.isCanMoveCannon = false;
        this.curCannonCtr.shootBullet(false)
    }

    cannonMove(dt){
    
        if(this.isCanMoveCannon){
            this.curCannonCtr.move(dt,this.isCanMoveCannon,this.moveToPos);
            this.shootBullet(dt);
            this.curCannonCtr.shootBullet(true)
        }
    }

    shootBullet(dt){

        let bulletCount:number = UserInfo.bulletShootMaxCount * Common.addPower
        //发射的子弹已经达到上限
        if(this.getCurValidBulletCount() >= bulletCount){
            return
        }
        this.totalShootTime =  this.totalShootTime + dt 
        //这里处理动作 限制动作的最快速度
        if(bulletCount >= 10)
        {
            this.totalShootAnimaTime = this.totalShootAnimaTime + dt
            if(this.totalShootAnimaTime > 0.1){
                this.totalShootAnimaTime = 0
                this.curCannonCtr.playAttack()
            }
        }else
        {
            if(this.totalShootTime > 1/bulletCount){
                this.curCannonCtr.playAttack()
            }
        }
        let count:number = bulletCount;
        if(count >= Define.bulletMacCount)
        {
            count = Define.bulletMacCount;
        }
        if(this.totalShootTime > 1/count) //20
        {
            this.totalShootCount++;
            let row   = Math.floor(bulletCount/Define.bulletMacCount)
            let count = Math.floor(bulletCount%Define.bulletMacCount)
            if(this.totalShootCount <= count)
            {
                row = row + 1
            }
            if(row <= 0)
            {
                row = 1
            }
            //子弹升级了火力
            let power = UserInfo.addFirePower
            if(this.totalShootCount < UserInfo.addFirePowerCount){
                power = power + 1
            }
            for (let index = 0; index < row; index++) {
                let offsetX = Common.getBulletOffsetX(row,index);
                let bullet =  this.getBullet();
                let v1 = new cc.Vec2(this.curCannonCtr.node.position.x,(this.curCannonCtr.node.position.y + 50));
                let v2 = new cc.Vec2(this.curCannonCtr.node.position.x + offsetX,(this.curCannonCtr.node.position.y + 1136));
                bullet.setPower(power)
                bullet.shoot(v1,v2);
            }
            this.totalShootTime = 0
        }
        if(this.totalShootCount > count)
        {
            this.totalShootCount = 0;
        }
    }

    isCanShakeBg:boolean = true
    ShakeBg(shakeLevel:number = 5){
        if(this.isCanShakeBg){
            this.isCanShakeBg = false
            this.nodeBg.runAction(cc.sequence(Shake.create(0.2,shakeLevel,shakeLevel),
                cc.callFunc(function(){
                    this.nodeBg.position = this.bgInitPos;
                    this.isCanShakeBg = true
                }.bind(this))
            ));
        }
    }

    getBullet():Bullet{
        let bullet:Bullet = null
        for (let index = 0; index < this.bulletArr.length; index++) {
            if(!this.bulletArr[index].isValidBullet){ //已经无效重新利用
                bullet = this.bulletArr[index];
            }
        }
        if(bullet == null)
        {
            bullet =  cc.instantiate(this.nodeBullet).getComponent(Bullet);
            Common.nodeBallRoot.addChild(bullet.node); 
            this.bulletArr.push(bullet);
        }
        //默认子弹的威力是1
        bullet.power = 1
        return bullet
    }
    //移除所有子弹
    removeAllBullet(){
        for (let index = 0; index < this.bulletArr.length; index++) {
            this.bulletArr[index].node.destroy();
        }
        this.bulletArr = []
    }

    getCurValidBulletCount():number{
        let count = 0;
        for (let index = 0; index < this.bulletArr.length; index++) {
            if(this.bulletArr[index].isValidBullet){
                count++;
            }
        }
        return count;
    }

    update (dt) {

        this.wxHelper.update(dt);
        if(Common.isPause || Common.isGameOver || !Common.isPlaying){
            return;
        }
    
        this.cannonMove(dt);
        this.handlerBulletCollision();
        TimeTaskManager.updateTime(dt);
    }
     
    handlerBulletCollision(){
        for (let index = 0; index < this.bulletArr.length; index++) {
            if(this.bulletArr[index].isValidBullet){
                this.checkIsBulletCollision(this.bulletArr[index]);
            }
        }
    }
    //单独子弹对 球进行检测
    checkIsBulletCollision(bullet:Bullet){
        for (let index = 0; index < this.ballArr.length; index++) {
    
            let ball = this.ballArr[index];            
            let isCollision = Common.isCollision(ball.node,bullet.node,ball.stoneData.radius);
            if(isCollision){
                bullet.setValid(false);
                ball.Hit(bullet.power);
                Common.totalShowScore = Common.totalShowScore + bullet.power;
                UserInfo.totalScore = UserInfo.totalScore + bullet.power;
                UIManager.getInstance().executeEvent(Define.viewBattle,"refreshScore");
                if(ball.getNumber() <= 0){
                    if(ball.stoneData.stonId == 0){
                        Common.curLevelScore++;
                        UIManager.getInstance().executeEvent(Define.viewBattle,"refreshProgressInfo");
                        
                        console.log("金币掉落................")
                        this.handlerGoldDrop(ball.node.position);
                        if(LevelInfo.isFinishLevel()){
                            //已经通过了关卡
                            console.log("已经通过了关卡。。。。。。。。。。。。。。。。。。。。")
                            this.handlerCollectAllGold() //收集所有金币
                            Common.isPlaying = false;

                            UIManager.getInstance().executeEvent(Define.viewBattle,"hideAddPower");
                            UIManager.getInstance().showView(Define.viewGameWin);
                            UserInfo.saveNextLevel();
                        }
                    }
                    //释放小球
                    this.ballArr.splice(index,1);
                    //这里创建新的小球
                    this.stoneBreakCallBack(ball);
                    ball.node.destroy();
                    ball = null;
                    break;
                }
            } 
        }
    }

    //检测是否存在最大的石块
    checkIsExsitMaxStone():boolean{
        for (let index = 0; index < this.ballArr.length; index++) {
            if(this.ballArr[index].stoneId == 3){
                return true;
            }
        }
        return false;
    }

    createStone(onlyTag:string,dir:number = 0,stoneId:number = -1,pos:cc.Vec2 = null,score:number = 0){

        if(Common.isPause || Common.isGameOver || !Common.isPlaying){
            return;
        }
        
        if(!LevelInfo.isCanCreateStone() && onlyTag != "stoneBreak"){
            console.log("已经创建到最大了。。。。。。。。。");
            return;
        }
        //已经有最大的不创建
        if((this.checkIsExsitMaxStone() || this.ballArr.length > Define.ballMaxCount )&& onlyTag != "stoneBreak"){
            return;
        }

        if(onlyTag != "stoneBreak"){
            stoneId = LevelInfo.getStoneId();
            if(stoneId == null){
                return;
            }
        }
        
        let ball =  cc.instantiate(this.nodeBalls.children[stoneId]).getComponent(Ball);
        ball.stoneId = stoneId;
        Common.nodeBallRoot.addChild(ball.node);
        
        if(onlyTag == "stoneBreak"){
            ball.appear(Define.center,dir,pos);
            ball.setNumber(score);
        }else{
            let stoneScore = LevelInfo.getStoneScore(Common.isFirstCreatStone);
            Common.isFirstCreatStone = false;
            ball.setNumber(stoneScore);
            ball.appear(Common.getRandom(0,2),dir,pos,LevelInfo.getStoneInitY());
        }
        this.ballArr.push(ball);
    }
    
    stoneBreakCallBack(ball:Ball){

        WXHelper.brateShort();
        let effect:ParticleEffect =  ParticleEffectManager.getInstance().showParticleEffect(3,ball.node.position,0.5);

        effect.node.scale = ball.stoneData.radius/40;

        if(ball.stoneId > 0){
            this.createStone("stoneBreak",Define.left,ball.stoneId-1,ball.node.position,ball.getBreakScore());
            this.createStone("stoneBreak",Define.right,ball.stoneId-1,ball.node.position,ball.getBreakScore());
        } 
    }
    //处理金币掉落
    handlerGoldDrop(pos:cc.Vec2){
       let count:number = LevelInfo.getDropGoldCount();
       if(count >= 0){
           for (let index = 0; index < count; index++) {
                let goldId = LevelInfo.getDropGoldId();
                this.getGold(goldId,pos);
           }
       }
    }
    //获得一个金币
    getGold(goldId:number,pos:cc.Vec2):GoldCtr{
        let goldCtr:GoldCtr = null
        for (let index = 0; index < this.goldArr.length; index++) {
            if(this.goldArr[index].isCanUseTag){
                goldCtr = this.goldArr[index];
            }
        }

        if(goldCtr == null){
            goldCtr = cc.instantiate(this.nodeGold).getComponent<GoldCtr>(GoldCtr);
            Common.nodeGoldRoot.addChild(goldCtr.node);
            this.goldArr.push(goldCtr);
        }
        goldCtr.node.position = pos;
        goldCtr.setGoldId(goldId);
        let frame:cc.SpriteFrame = this.nodeGolds.children[goldId].getComponent(cc.Sprite).spriteFrame;
        goldCtr.setIcon(frame);

        return goldCtr;
    }

    //收集所有金币
    handlerCollectAllGold(){
        for (let index = 0; index < this.goldArr.length; index++) {
            this.goldArr[index].autoCollect();
        }
    }

    //收集的金币
    handlerCollectGold(goldCount:number){
        UserInfo.curGold = UserInfo.curGold + goldCount;
        UIManager.getInstance().executeEvent(Define.viewBattle,"refreshGold")
    }

    //移除所有的石头
    removeAllStone(){
        for (let index = 0; index < this.ballArr.length; index++) {
            this.ballArr[index].node.destroy();
            this.ballArr[index] = null;
        }
        this.ballArr = [];
    }
    //金币没有被释放 重复利用
    clearAllGold(){
        for (let index = 0; index < this.goldArr.length; index++) {
            this.goldArr[index].clear();
        }
    }
    //重新开始游戏调用
    restartGame(){
        //清空上一局数据
        this.removeAllStone();

        this.curCannonCtr.openCollision();
        
        LevelInfo.InitLevelStoneInfo();

        Common.resetDatas();

        UIManager.getInstance().refreshView(Define.viewBattle);
        
        //出现石块
        Common.isGameOver = false;
        Common.isPause = false;
        Common.isPlaying = true;
        this.createStone("");
    }
    //退出游戏
    exitGame(){
        Common.lastShowScore = 0;
        this.removeAllStone(); //清理石头
        this.clearAllGold(); //清理金币
    }
    
    gameOver(ball:Ball){
     
        if(ball != null){
            if(Common.isGameOver){
                return
            }
            Common.isGameOver = true;
            this.pauseStoneMove(true);
            this.showGameOverEffect()
        }else {
            UserInfo.saveGoldData();
            this.exitGame();
            UIManager.getInstance().executeEvent(Define.viewBattle,"hideAddPower");
            UIManager.getInstance().showView(Define.viewGameResult);  
        }
    }

    //显示结算失败效果
    showGameOverEffect(){
        WXHelper.brateLong();
        this.curCannonCtr.die(function(){
            if(Common.isCanRevive){
                Common.isCanRevive = false;
                UIManager.getInstance().executeEvent(Define.viewBattle,"hideAddPower");
                UIManager.getInstance().showView(Define.viewRevive); 
    
            }else{
                //显示结算失败
                WXHelper.instance.submitScore();
    
                UserInfo.saveGoldData();
                this.exitGame();
                UIManager.getInstance().executeEvent(Define.viewBattle,"hideAddPower");
                UIManager.getInstance().showView(Define.viewGameResult);    
            }
        }.bind(this))
    }

    //视频或者点击金币复活了
    reviveGame(){
        UserInfo.god(3)
        this.pauseStoneMove(false)
        Common.isGameOver = false;
    }

    pauseStoneMove(isPause:boolean){
        for (let index = 0; index < this.ballArr.length; index++) {
           this.ballArr[index].pauseMove(isPause);
        }
    }

    gameEventHide(){
        console.log("gameEventHide")
        cc.director.pause();
        UserInfo.saveLastQuitTime()
    }

    gameEventShow(){
        console.log("gameEventShow")
        if(cc.director.isPaused()){
            cc.director.resume();
        }
        if(UIManager.getInstance().isShow(Define.viewSelectCannon)){ //这里分享获得大炮
            UIManager.getInstance().executeEvent(Define.viewSelectCannon);
        }else if(UIManager.getInstance().isShow(Define.viewUpgrade)){
            UIManager.getInstance().executeEvent(Define.viewUpgrade,);
        }else if(UIManager.getInstance().isShow(Define.viewBattle)){
            UIManager.getInstance().executeEvent(Define.viewBattle,"share");
        }else if(UIManager.getInstance().isShow(Define.viewSelectScene)){
            UIManager.getInstance().executeEvent(Define.viewSelectScene);
        }
    }
}

